<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Ldap
 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Children.php 10 2008-11-08 17:17:02Z Stefan.Gehrig.HN $
 */

/** 
 * Zend_Ldap_Exception
 */
require_once 'Zend/Ldap/Exception.php';
/** 
 * Zend_Ldap_Node 
 */
require_once 'Zend/Ldap/Node.php';
/** 
 * Zend_Ldap_QueryResult 
 */
require_once 'Zend/Ldap/QueryResult.php';


/**
 * Zend_Ldap_Node_Children provides a collecion of child nodes..
 *
 * @category   Zend
 * @package    Zend_Ldap
 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Ldap_Node_Children implements Iterator, RecursiveIterator, Countable 
{
    /**
     * The node to which this collection belongs to.
     *
     * @var Zend_Ldap_Node
     */
    private $_parent;
    /**
     * The query result.
     *
     * @var Zend_Ldap_QueryResult
     */
    private $_queryResult;
    /**
     * Iteration object cache.
     *
     * @var array of Zend_Ldap_Node
     */
    private $_cache;
    
    /**
     * Creates a new Zend_Ldap_Node_Children collection.
     *
     * @param Zend_Ldap_Node $parentNode
     * @param Zend_Ldap_QueryResult $queryResult
     */
    public function __construct(Zend_Ldap_Node $parentNode, Zend_Ldap_QueryResult $queryResult)
    {
        $this->_parent=$parentNode;
        $this->_queryResult=$queryResult;
        $this->_cache=array();
    }
    
    /**
     * Returns the sub iterator for the current child node.
     * Implements RecursiveIterator
     *
     * @return Zend_Ldap_Node_Children 
     */ 
    public function getChildren()
    {
        if (is_null($this->current())) return null;
        return $this->current()->getChildren();
    }
    
    /**
     * Checks if current node has children.
     * Returns whether the current element has children.
     * Implements RecursiveIterator
     *
     * @return boolean 
     * @throws Zend_Ldap_Exception
     */
    public function hasChildren()
    {
        if (is_null($this->current())) return false;
        return ($this->current()->getChildren()->count()>0);
    }
    
    /**
     * Returns the number of children in node.
     * Implements Countable
     *
     * @return int
     * @throws Zend_Ldap_Exception
     */
    public function count()
    {
        return $this->_queryResult->count();
    }
    
    /**
     * Return the current child node.
     * Implements Iterator and RecursiveIterator
     *
     * @return Zend_Ldap_Node
     */
    public function current()
    {
        $current=$this->_queryResult->current();
        if (is_null($current)) return null;
        if (!isset($this->_cache[$current['dn']])) {
             $node=Zend_Ldap_Node::fromArray($current);
             $node->attachLdap($this->_parent->getLdap());
             $this->_cache[$current['dn']]=$node;
        }
        return $this->_cache[$current['dn']];
    }
    
    /**
     * Return the child key (DN).
     * Implements Iterator and RecursiveIterator
     *
     * @return string
     */
    public function key()
    {
        if (is_null($this->current())) return null;
        return $this->current()->getDn();
    }
    
    /**
     * Move forward to next child node.
     * Implements Iterator and RecursiveIterator
     */
    public function next()
    {
        $this->_queryResult->next();
    }
    
    /**
     * Rewind the Iterator to the first child node.
     * Implements Iterator and RecursiveIterator
     * 
     * @throws Zend_Ldap_Exception
     */
    public function rewind()
    {
        $this->_queryResult->rewind();
    }
    
    /**
     * Check if there is a current child node
     * after calls to rewind() or next().
     * Implements Iterator and RecursiveIterator
     *
     * @return bool
     */
    public function valid()
    {
        return $this->_queryResult->valid();
    }
    
    /**
     * Copies all child nodes into an array.
     *
     * @return array
     */
    public function toArray()
    {
        $array=array();
        foreach ($this as $n) {
            $array[]=$n;
        }
        return $array;
    }
}